package dev.werillib.net

import android.net.ParseException
import org.json.JSONException
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException

class ExceptionHandle {

    /**
     * 约定异常
     */
    internal object ERROR {
        /**
         * 未知错误
         */
        const val UNKNOWN = 1000
        /**
         * 解析错误
         */
        const val PARSE_ERROR = 1001
        /**
         * 网络错误
         */
        const val NETWORK_ERROR = 1002
        /**
         * 协议出错
         */
        const val HTTP_ERROR = 1003
        /**
         * 证书出错
         */
        const val SSL_ERROR = 1004
    }

    class ResponseThrowable internal constructor(throwable: Throwable, var code: Int) :
        Exception(throwable) {
        override var message: String? = null
    }

    /**
     * ServerException发生后，将自动转换为ResponseThrowable返回
     */
    internal inner class ServerException : RuntimeException() {
        var code: Int = 0
        override var message: String? = null
    }

    companion object {
        private const val UNAUTHORIZED = 401
        private const val FORBIDDEN = 403
        private const val NOT_FOUND = 404
        private const val REQUEST_TIMEOUT = 408
        private const val INTERNAL_SERVER_ERROR = 500
        private const val BAD_GATEWAY = 502
        private const val SERVICE_UNAVAILABLE = 503
        private const val GATEWAY_TIMEOUT = 504

        fun handleException(e: Throwable): ResponseThrowable {
            val ex: ResponseThrowable
            if (e is HttpException) {
                ex = ResponseThrowable(
                    e,
                    ERROR.HTTP_ERROR
                )
                when (e.code()) {
                    UNAUTHORIZED -> ex.message = "请求无权限"
                    FORBIDDEN -> ex.message = "拒绝请求"
                    NOT_FOUND -> ex.message = "请求失败"
                    REQUEST_TIMEOUT -> ex.message = "请求超时"
                    GATEWAY_TIMEOUT -> ex.message = "响应超时"
                    INTERNAL_SERVER_ERROR -> ex.message = "服务器错误"
                    BAD_GATEWAY -> ex.message = "响应错误"
                    SERVICE_UNAVAILABLE -> ex.message = "服务不可用"
                    else -> ex.message = "网络异常"
                }
                return ex
            } else if (e is ServerException) {
                ex = ResponseThrowable(e, e.code)
                ex.message = e.message
                return ex
            } else if (e is ParseException || e is JSONException) {
                ex = ResponseThrowable(
                    e,
                    ERROR.PARSE_ERROR
                )
                ex.message = "解析错误"
                return ex
            } else if (e is ConnectException) {
                ex = ResponseThrowable(
                    e,
                    ERROR.NETWORK_ERROR
                )
                ex.message = "网络异常"
                return ex
            } else if (e is SocketTimeoutException) {
                ex = ResponseThrowable(
                    e,
                    ERROR.NETWORK_ERROR
                )
                ex.message = "连接服务器超时"
                return ex

            } else if (e is javax.net.ssl.SSLHandshakeException) {
                ex = ResponseThrowable(
                    e,
                    ERROR.SSL_ERROR
                )
                ex.message = "证书验证失败"
                return ex
            } else {
                ex = ResponseThrowable(
                    e,
                    ERROR.UNKNOWN
                )
                ex.message = "数据异常"
                return ex
            }
        }
    }
}
